/** 
 * @author Riccardo Manfrin [namesurname at gmail dot com]
 * 
 * @brief  KILLNET APP FILE
 * 
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h> /* usleep */
#include "sock.h"
#include "parser.h"
#include "rdata.h"
#include "wifi.h"
#include "debug.h"

#define 	OP_SZ 	20
#define 	ARG_SZ 	OP_SZ
#define 	MAX_ARGS 7

enum {
	TCP_MISSING_IP_OR_PORT
} err_code;

static unsigned int lat = 0;
static unsigned int pktsz = 0;
static unsigned int npkts = 1;

static void error(int e);
static void set_lat(unsigned int i);
static void set_npkts(unsigned int i);
static void set_pktsz(unsigned int i);

static void error(int e)
{
	printf("rdata.c : ERR_CODE %i\n",(int)e);
	return;
}

static void set_lat(unsigned int i)
{
	lat = i;
	return;
}
static void set_npkts(unsigned int i)
{
	npkts = i;
	return;
}
static void set_pktsz(unsigned int i)
{
	pktsz=i;
	return;
}

void parse(char *cmdline){
	int i;
	char **args;
	char *ptr;
	char *cmd = malloc(OP_SZ);
	memset(cmd,0,OP_SZ);
	sscanf(cmdline, "%s", cmd);
	if(memcmp(cmd,"#",1)==0) return;
	
	args = malloc(sizeof(char *) * MAX_ARGS);
	i = 0;
	ptr = cmdline + strlen(cmd);
	for(i = 0; i < MAX_ARGS; i++)
	{
		args[i] = malloc(ARG_SZ);
		memset(args[i],0,ARG_SZ);
		sscanf(ptr, "%s", args[i]);
		ptr = ptr + strlen(args[i]) + 1;
	}
	
	if(memcmp("open",cmd,4)==0)
	{
		for (i=0;i<MAX_ARGS;i++)
		{
			//printf("OPEN - %s\n",args[i]);
			int tcp=0; int tcp_dstip=0; int tcp_dstport=0;
			if(memcmp(args[i],"tcp",3)==0) {set_transport(TCP);tcp=1;}
			if(memcmp(args[i],"udp",3)==0) set_transport(UDP);
			if(memcmp(args[i],"uc",2)==0) set_skt_txmode(UC);
			if(memcmp(args[i],"bc",2)==0) set_skt_txmode(BC);
			if(memcmp(args[i],"mc",2)==0) set_skt_txmode(MC);
			if(memcmp(args[i],"iface=",6)==0) set_iface((char*)(args[i]+6));
			if(memcmp(args[i],"srcip=",6)==0) set_src_addr((char*)(args[i]+6));
			if(memcmp(args[i],"dstip=",6)==0) {set_dst_addr((char*)(args[i]+6)); tcp_dstip=1;}
			if(memcmp(args[i],"port=",5)==0) set_src_port(atoi((char*)(args[i]+5)));
			if(memcmp(args[i],"dstport=",8)==0) {set_dst_port(atoi((char*)(args[i]+5))); tcp_dstport=1;}
			//Downgrading the socket to UDP because information is missing.
			if(tcp==1 && (tcp_dstip==0 || tcp_dstport==0))
			{
				set_transport(UDP);
				error(TCP_MISSING_IP_OR_PORT);
			}
		}
		sock_open();
	}
	else if(memcmp("set",cmd,3)==0)
	{
		sscanf(cmdline, "%*s %s %s", args[0], args[1]);
		for (i=0;i<MAX_ARGS;i++)
		{
			if(memcmp(args[i],"rate=",5)==0) wifi_setRate(atof((char*)(args[i]+5)));
			if(memcmp(args[i],"channel=",8)==0) wifi_setCh(atof((char*)(args[i]+8)));
		}
	}
	else if(memcmp("sleep", cmd, 5)==0)
	{
		int l;
		sscanf(cmdline, "%*s %i", &l);
		usleep(l);
	}
	else if(memcmp("send",cmd,4)==0)
	{
		for (i=0;i<MAX_ARGS;i++)
		{
			//printf("SEND - %s\n",args[i]);
			if(memcmp(args[i],"ip=",3)==0) set_dst_addr((char*)(args[i]+3));
			if(memcmp(args[i],"port=",5)==0) set_dst_port(atoi((char*)(args[i]+5)));
			if(memcmp(args[i],"lat=",4)==0) set_lat(atoi((char*)(args[i]+4)));
			if(memcmp(args[i],"npkts=",6)==0) set_npkts(atoi((char*)(args[i]+6)));
			if(memcmp(args[i],"sz=",3)==0) set_pktsz(atoi((char*)(args[i]+3)));
			if(memcmp(args[i],"static",6)==0) {rdata_init(STATIC);}
			if(memcmp(args[i],"dynamic",7)==0) {rdata_init(DYNAMIC);}
			if(memcmp(args[i],"sequence",7)==0) {rdata_set(SEQUENCE, 1);}
			else rdata_set(SEQUENCE, 0);
		}
		for(i=0;i<npkts;i++)
		{
			sock_send(get_sockfd(), rdata_gen(pktsz),pktsz);
			if(lat>0) usleep(lat);
		}
		dbg_print(CHR, "parser.c: SENT\n");
	}
	else if(memcmp("close",cmd,5)==0)
	{
		rdata_free();
		sock_close(get_sockfd());
	}
	else
	{
		/** 
		 * Non supported command or other stuff
		 */
	}	
	free(cmd);
	for(i = 0; i < MAX_ARGS; i++)
	{
		free(args[i]);
	}
	return;
}


